#ifndef _FFT_H_2011_8_3
#define _FFT_H_2011_8_3
//------------------------------------
//  Reliable Software, (c) 1996-2002
//------------------------------------
#include <vector>
#include <complex>
#include <cassert>

class Fft
{
public:
    Fft (unsigned points, unsigned sampleRate);
	// Hard work
    void    Transform (std::vector<int> const & data);
	// Output: from i = 0 to points-1
    double  GetIntensity (unsigned i) const
    { 
        assert (i < _points);
        return std::abs (_x[i])/_sqrtPoints;
    }
    unsigned Points () const { return _points; }
	// return frequency in Hz of a given point
    int GetFrequency (unsigned point) const
    {
        assert (point < _points);
        long x =_sampleRate * point;
        return x / _points;
    }
    int HzToPoint (int freq) const 
    { 
        return (long)_points * freq / _sampleRate; 
    }
    int MaxFreq() const { return _sampleRate; }

	// add by lbw 110803
	void SetSampleRate(unsigned sampleRate) {_sampleRate=sampleRate;}
private:
	void DataIn (std::vector<int> const & data);
    void PutAt (unsigned i, double val)
    {
    	_x [_aBitRev[i]] = std::complex<double> (val);
    }
private:
    unsigned	_points;
    unsigned	_sampleRate;
    unsigned	_logPoints;		// binary log of _points
    double		_sqrtPoints;	// square root of _points

    std::vector< std::complex<double> >				_x;	// in-place fft array
	std::vector<unsigned>				_aBitRev;	// bit reverse vector
	std::vector< std::vector< std::complex<double> > >	_w;	// exponentials
	std::vector<double>					_tape;	// recording tape
};

#endif	// _FFT_H_2011_8_3
